---
title: "SSRM Tree Data"
enterprise: true
---

This section shows how Tree Data can be used with the Server-Side Row Model.

## Tree Data

Tree Data is defined as data that has parent / child relationships where the parent / child relationships are
provided as part of the data. This is in contrast to Row Grouping where the parent / child relationships are
the result of grouping. When working with Tree Data, there are no columns getting grouped.

An example of a Tree Data JSON structure is shown below:

```json
[{
    "employeeId": 101,
    "employeeName": "Erica Rogers",
    "jobTitle": "CEO",
    "employmentType": "Permanent",
    "children": [{
        "employeeId": 102,
        "employeeName": "Malcolm Barrett",
        "jobTitle": "Exec. Vice President",
        "employmentType": "Permanent",
        "children": [
            {
                "employeeId": 103,
                "employeeName": "Leah Flowers",
                "jobTitle": "Parts Technician",
                "employmentType": "Contract"
            },
            {
                "employeeId": 104,
                "employeeName": "Tammy Sutton",
                "jobTitle": "Service Technician",
                "employmentType": "Contract"
            }
        ]
    }]
}]
```

It is expected that the data set will be too large to send over the network, hence the SSRM is used to
lazy-load child row as the parent rows are expanded.

## Tree Data Mode

In order to set the grid to work with Tree Data, simply enable Tree Data mode via the Grid Options
using: `gridOptions.treeData = true`.

## Supplying Tree Data

Tree Data is supplied via the [Server-Side Datasource](./server-side-model-datasource/) just like flat data,
however there are two additional gridOptions callbacks: `isServerSideGroup(dataItem)`
and `getServerSideGroupKey(dataItem)`.

{% apiDocumentation source="grid-options/properties.json" section="serverSideRowModel" names=["isServerSideGroup", "getServerSideGroupKey"] /%}

The following code snippet shows the relevant `gridOptions` entries for configuring tree data with the
server-side row model:

```{% frameworkTransform=true spaceBetweenProperties=true %}
const gridOptions = {
    // choose Server-Side Row Model
    rowModelType: 'serverSide',
    // enable Tree Data
    treeData: true,
    // indicate if row is a group node
    isServerSideGroup: dataItem => {
        return dataItem.group;
    },
    // specify which group key to use
    getServerSideGroupKey: dataItem => {
        return dataItem.employeeId;
    },
}
```

{% note %}
Be careful not to get mixed up with the [Client-Side Tree Data](./tree-data/) configurations by mistake.
{% /note %}

The example below shows this in action where the following can be noted:

* Tree Data is enabled with the Server-Side Row Model using `gridOptions.treeData = true`.
* Group nodes are determined using the callback `gridOptions.isServerSideGroup(dataItem)`.
* Group keys are returned from the callback `gridOptions.getServerSideGroupKey(dataItem)`.

{% gridExampleRunner title="Tree Data" name="tree-data"  exampleHeight=590 /%}

## Refreshing Tree Data

Tree Data can be refreshed in the same way as groups are refreshed when not using Tree Data. This is
explained in the [SSRM Refresh](./server-side-model-updating-refresh/).

The example below shows this in action where the following can be noted:

* Click **Refresh Everything** to clear all caches by calling `api.refreshServerSide({ route: [], purge: true })`.
* Click **Refresh \['Kathryn Powers','Mabel Ward']** to clear a single cache by calling `api.refreshServerSide({ route: ['Kathryn Powers','Mabel Ward'], purge: true })`.

{% gridExampleRunner title="Purging Tree Data" name="purging-tree-data"  exampleHeight=615 /%}

## Transactions with Tree Data

Tree Data can have transactions applied in the same way as row groups. This is explained in the [SSRM Transactions](./server-side-model-updating-transactions/) section.

The example below demonstrates transactions with Tree Data. Note the following:

* **Add Child to Selected** adds a child under the selected row, even if it wasn't originally a group.
* **Update Selected** changes the selected row's `Employment Type`.
* **Delete Selected** removes the selected row, and all of its child rows.
* **Move Selected to Robert Peterson** moves the selected row and its children directly under `Robert Peterson`.

{% gridExampleRunner title="Transactions with Tree Data" name="transactions-tree-data"  exampleHeight=615 /%}

## Selection with Tree Data

Tree Data can have row selection applied in the same way as row groups. This is explained in the [SSRM Row Selection](./server-side-model-selection/) section.

The example below demonstrates row selection with Tree Data where the grid has been configured with `rowSelection.groupSelects = 'descendants'`. 
This means that selecting a row with descendants selects all of its descendants. Selecting some, but not all, of the descendants of a row places that row in the indeterminate state.

{% gridExampleRunner title="Selection with Tree Data" name="selecting-tree-data"  exampleHeight=615 /%}

## Filtering Tree Data

Server-Side Tree Data Filtering should behave the same as Client-Side [Tree Data Filtering](./tree-data-filtering). A group will be included if:

1. it has any children that pass the filter, or

1. it has a parent that passes the filter, or

1. its own data passes the filter

The following example demonstrates Server-Side Tree Data Filtering using the [Set Filter Tree List](./filter-set-tree-list/), which replicates the Tree Data structure in the filter.

* The **Group** column has the Set Filter Tree List enabled via `filterParams.treeList = true`. A Key Creator is specified to convert the path into a string.
* The **Group** column has the filter values supplied asynchronously as a nested array of strings that matches the data paths. The supplied values are at the child level only.
* The **Date** column has the Set Filter Tree List enabled via `filterParams.treeList = true`, and is grouped by year -> month -> day.
* The **Date** column has the filter values supplied asynchronously as an array of `Date` objects.
* The **Date** column has a `filterParams.keyCreator` provided to convert the `Date` values into the (string) format the server is expecting in the Filter Model.
* The **Group** and **Date** columns both have `filterParams.excelMode = 'windows'`, which allows changes to the tree filter to be applied in batches.

{% gridExampleRunner title="Filtering Tree Data" name="filtering-tree-data"  exampleHeight=590 /%}

## Providing Hierarchical Data via API

Below is an example of utilising `api.applyServerSideRowData` to populate data. The datasource is only used to provide root level rows, and when these are loaded the grid is provided the child row data via the API.

{% gridExampleRunner title="Hierarchical Data" name="supplying-hierarchy" /%}

Continue to the next section to learn how to combine [Master Detail](./server-side-model-master-detail/) with the SSRM.
